#pragma once
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdarg>
#include <ctime>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
using namespace std;



enum { // 枚举日志等级
    Info = 0,
    Debug,
    Waring,
    Err,
    Fatal
};
vector<string> LevelToString = { "Info", "Debug", "Waring", "Err", "Fatal" };


// 枚举打印模式
enum {
    Screen = 1,
    OneFile,
    CalssFile
};

const int default_style = Screen;
const string default_dir_name = "log";
const string default_filename = "log.";



class Log {
public:
    Log() 
        :_style(default_style)
        ,_filename(default_filename)
    {
        mkdir(default_dir_name.c_str(), 0775); // 创建日志文件夹
    }

    void Enable(int style) {
        _style = style;
    }

    // 将时间戳转化成年月日时分秒的形式
    string TimestampToLocaltime(const time_t currtime) {
        struct tm *cur = localtime(&currtime);
        if (cur == nullptr) {
            exit(-1);
        }
        char timebuffer[128];
        snprintf(timebuffer, sizeof timebuffer, "%d-%d-%d %d:%d:%d", cur->tm_year + 1900, cur->tm_mon + 1, cur->tm_mday, \
        cur->tm_hour, cur->tm_min, cur->tm_sec);
        return timebuffer;
    }

    // 打印日志信息到一个文件
    void PrintLogToOneFile(const string level, const string& LogInfo) {
        string filename = default_dir_name + "/" + _filename + level;
        umask(0);
        int fd = open(filename.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0666);
        if (fd < 0) {
            exit(-1);
        }
        // 写入文件
        write(fd, LogInfo.c_str(), LogInfo.size());
        close(fd); // 关闭文件
        
    }

    // 打印日志到文件
    void PrintLogToFile(const int level, const string& LogInfo) {
        if (_style == Screen) {
            cout << LogInfo << endl;
        } else if (_style == OneFile) {
            PrintLogToOneFile("All", LogInfo + "\n");
        } else {
            PrintLogToOneFile(LevelToString[level], LogInfo + "\n");
        }
        
    }


    // 打印日志
    void PrintLog(int level, const char* format, ...) {
        va_list args;
        va_start(args, format); // args指向了可变参数部分
        char rightbuffer[1024];
        vsnprintf(rightbuffer, sizeof rightbuffer, format, args);
        va_end(args); // args指向了nullptr

        // 获取当前时间
        time_t currtime = time(nullptr);
        char leftbuffer[1024];
        snprintf(leftbuffer, sizeof leftbuffer, "[%s][process:%s][%s] ", LevelToString[level].c_str(), \
        to_string(getpid()).c_str(), TimestampToLocaltime(currtime).c_str());
        string LogInfo = leftbuffer;
        LogInfo += rightbuffer;
        // 将日志信息打印到文件
        PrintLogToFile(level, LogInfo);
    }

    ~Log() {

    }
private:
    int _style;
    string _filename;
};

// 定义一个全局的日志
Log lg;
